package cn.lrwjz.geotest.ui;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.geo.parse.GnssRefStationData;
import com.geo.parse.GnssSateInfo;
import com.geo.parse.GnssSateInfoList;
import com.google.android.material.appbar.MaterialToolbar;

import org.greenrobot.eventbus.EventBus;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import cn.lrwjz.geotest.R;
import cn.lrwjz.geotest.adapter.DeviceBluetoothAdapter;
import cn.lrwjz.geotest.bluetooth.BlueToothBroadcastReceiver;
import cn.lrwjz.geotest.bluetooth.BlueToothInit;
import cn.lrwjz.geotest.bluetooth.IBlueToothDeviceFoundListener;
import cn.lrwjz.geotest.bluetooth.IBondStateListener;
import cn.lrwjz.geotest.event.LocationUpdateEvent;
import cn.lrwjz.geotest.event.PowerBatteryLevelEvent;
import cn.lrwjz.geotest.utils.SpUtils;
import geo.com.geosdk.GeoManage;
import geo.com.geosdk.listener.ConnectListener;
import geo.com.geosdk.listener.GeoLocationDataInterface;
import geo.com.geosdk.listener.GnssOutputDataListener;
import geo.com.geosdk.listener.PowerUpdateListener;

public class CommunicationSetupActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int MSG_CONNECT_SUCC = 1;
    private static final int MSG_CONNECT_DEFAIL = 2;
    private static final int MSG_DISCONNECT = 3;
    private static final int MSG_RECEIVE_DATA = 4;
    public static final String LAST_DEVICE ="lastDevice";
    private TextView tvDeviceName;
    private TextView tvLoadingTitle;
    private Button btnSearch;
    private Button btnStopSearch;
    private Button btnDisconnect;
    private Button btnConnect;
    private Button btnBreakOff;
    private FrameLayout flLoading;
    private LinearLayout llConnect;
    private LinearLayout llSerach;
    private LinearLayout llDisconnect;
    private LinearLayout llBreakOff;
    private RecyclerView ryBluetooth;
    private LocationManager locManager;
    private BluetoothAdapter bluetoothAdapter;
    private DeviceBluetoothAdapter deviceBluetoothAdapter;
    private BlueToothInit operateBlueTooth;

    private BlueToothBroadcastReceiver blueToothBroadcastReceiver;
    private BluetoothDevice device;

    public Set<BluetoothDevice> bondedDevices;
    public HashSet<BluetoothDevice> sets=new HashSet<>();

    private MainHandler mainHandler;
    class MainHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CONNECT_SUCC:
                    whenConnectSucc();
                    break;
                case MSG_CONNECT_DEFAIL:
                    whenConnectDefail();
                    break;
                case MSG_DISCONNECT:
                    whenDisConnect();
                    break;
                case MSG_RECEIVE_DATA:
                    break;
            }
        }
    }

    // 在类的开始处添加枚举定义
    private enum BluetoothState {
        INITIAL,         // 初始状态
        SEARCHING,       // 搜索中
        CONNECTING,      // 连接中
        CONNECTED,       // 已连接
        DISCONNECTING    // 断开连接中
    }

    // 添加状态变量
    private BluetoothState currentState = BluetoothState.INITIAL;

    // 添加状态管理方法
    private void updateUIState(BluetoothState newState) {
        currentState = newState;
        
        // 重置所有状态
        llConnect.setVisibility(View.GONE);
        llSerach.setVisibility(View.GONE);
        llDisconnect.setVisibility(View.GONE);
        llBreakOff.setVisibility(View.GONE);
        flLoading.setVisibility(View.GONE);

        switch (newState) {
            case INITIAL:
                llConnect.setVisibility(View.VISIBLE);
                tvDeviceName.setText("无连接设备");
                break;

            case SEARCHING:
                llSerach.setVisibility(View.VISIBLE);
                flLoading.setVisibility(View.VISIBLE);
                tvLoadingTitle.setText("搜索中...");
                break;

            case CONNECTING:
                llDisconnect.setVisibility(View.VISIBLE);
                flLoading.setVisibility(View.VISIBLE);
                tvLoadingTitle.setText("正在连接...");
                break;

            case CONNECTED:
                llBreakOff.setVisibility(View.VISIBLE);
                if (device != null) {
                    tvDeviceName.setText(getDeviceName(device));
                    SpUtils.obtain().putString(LAST_DEVICE, device.getAddress());
                }
                break;

            case DISCONNECTING:
                flLoading.setVisibility(View.VISIBLE);
                tvLoadingTitle.setText("断开连接中...");
                break;
        }
    }

    // 修改现有的状态处理方法
    private void whenConnectSucc() {
        updateUIState(BluetoothState.CONNECTED);
        finish();
    }

    private void whenConnectDefail() {
        showToast("连接失败");
        updateUIState(BluetoothState.INITIAL);
    }

    private void whenDisConnect() {
        updateUIState(BluetoothState.INITIAL);
    }

    private void whenConnected() {
        updateUIState(BluetoothState.CONNECTED);
    }

    private void realStartConnect() {
        updateUIState(BluetoothState.CONNECTING);
        String blueToothAdress = device.getAddress();
        GeoManage.getInstance().setBlueToothAddress(blueToothAdress);
        GeoManage.getInstance().startConnectBlueTooth();
    }

    // 修改蓝牙搜索监听器
    private void registerBlueToothReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        blueToothBroadcastReceiver = BlueToothBroadcastReceiver.getSingleton();
        registerReceiver(blueToothBroadcastReceiver, filter);

        blueToothBroadcastReceiver.setBlueToothDeviceFoundListener(new IBlueToothDeviceFoundListener() {
            @Override
            public void onBlueToothDeviceFound(BluetoothDevice device, Intent intent) {
                if(sets.add(device)){
                    deviceBluetoothAdapter.addItem(device);
                }
            }
            
            @Override
            public void onBlueToothSearching() {
                updateUIState(BluetoothState.SEARCHING);
            }

            @Override
            public void onBlueToothSearched() {
                updateUIState(BluetoothState.INITIAL);
            }
        });

        blueToothBroadcastReceiver.setBlueToothBondListener(new IBondStateListener() {
            @Override
            public void bonded() {
                realStartConnect();
                showToast("匹配成功");
            }

            @Override
            public void bonding() {
                updateUIState(BluetoothState.CONNECTING);
//                showToast("正在匹配");
            }

            @Override
            public void bondNone() {
                updateUIState(BluetoothState.INITIAL);
                showToast("匹配失败");
            }
        });
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_communication_setup);

        // 设置工具栏
        MaterialToolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setTitle("通讯设置");
        }

        initView();
        initListener();
        initData();
    }

    private void initData() {
        try {
            // 初始化 SpUtils
            SpUtils.init(getApplicationContext());

            mainHandler = new MainHandler();

            locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
            //初始化蓝牙相关配置
            initBlueTooth();

            //判断蓝牙按钮是否打开--打开的话显示已经匹配过的蓝牙信息
            if(operateBlueTooth != null && operateBlueTooth.isOpenBlueTooth()){
                whenOpenBlueTooth();
            }

            //判断是不是连接状态--是的话显示连接状态
            if (GeoManage.getInstance().isConnectedBlueTooth()) {
                //是连接成功
                whenConnected();
            }

            deviceBluetoothAdapter.setOnItemClickListener((item, position) -> {
                deviceBluetoothAdapter.setmIsClick(true);
                deviceBluetoothAdapter.setCurrentItem(position);
                deviceBluetoothAdapter.notifyDataSetChanged();
                device = item;
            });

            //关于连接的回调
            connectCallback();

            //关于定位信息的回调
            locationCallback();

            //电量回调
            powerBatteryLevelCallback();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void powerBatteryLevelCallback() {
        //电池电量监听，每30s更新一次
        GeoManage.getInstance().setPowerUpdateListener(new PowerUpdateListener() {
            @Override
            public void onPowerUpdateListener() {
                EventBus.getDefault().postSticky(new PowerBatteryLevelEvent());
            }
        });

    }

    private void connectCallback() {
        //1.连接成功/失败的回调--此时在子线程中，不允许里面更新UI
        GeoManage.getInstance().setConnectListener(new ConnectListener() {
            @Override
            public void OnConnectCallBack(boolean bSucceed) {
                //是否连接成功---更新UI
                if(bSucceed){
                    //4.自动重连功能---手动断开和自动断开
                    //1.设置当前操作需不需要自动重连，区分自己断开连接和自动断开连接
                    //2.开始自动重连监听，更新UI，进行重新连接
                    GeoManage.getInstance().setAutoConnectBlueTooth(true);
                    mainHandler.sendEmptyMessage(MSG_CONNECT_SUCC);
                }else{
                    GeoManage.getInstance().setAutoConnectBlueTooth(false);//没连接成功不进行自动重连，只有连接成功之后断开才进行自动重连
                    mainHandler.sendEmptyMessage(MSG_CONNECT_DEFAIL);
                }
            }
            @Override
            public void OnDisConnectCallBack() {
                //连接成功后面中途断开---进行UI更新
                mainHandler.sendEmptyMessage(MSG_DISCONNECT);
            }
        });
    }

    private void locationCallback() {
        //GNSS数据输出--定位信息、卫星信息、基站信息、RTK回复数据
        //GeoLocationDataInterface--包含GNSS相关数据
        GeoManage.getInstance().setGnssOutputDataListener(new GnssOutputDataListener() {
            @Override
            public void OnGnssLocationCallBack(GeoLocationDataInterface geoLocationDataInterface) {
                //有定位数据变化--通知更新定位信息相关UI界面
                EventBus.getDefault().postSticky(new LocationUpdateEvent(geoLocationDataInterface));
            }

            @Override
            public void OnGnssRefStationCallBack(GeoLocationDataInterface geoLocationDataInterface) {
                //有基站数据更新--基站相关数据
                GnssRefStationData gnssRefStationData = geoLocationDataInterface.getRefStationData();
            }

            @Override
            public void OnGnssSateInfoBack(GeoLocationDataInterface geoLocationDataInterface) {
                //有卫星信息更新--星图星表UI
                //具体使用如下：
                GnssSateInfoList sateInfoList = geoLocationDataInterface.getSateInfoList();
                for(int i=0;i<sateInfoList.getSateInfoList().size();i++){
                    GnssSateInfo gnssSateInfo=sateInfoList.getSateInfoList().get(i);
                    int type = gnssSateInfo.getType().swigValue();//type卫星类型
                    switch (type){
                        case 1://SATSYS_GPS
                            break;
                        case 2://SATSYS_GLONASS
                            break;
                        case 3://SATSYS_SBAS
                            break;
                        case 4://SATSYS_GALILEO
                            break;
                        case 5://SATSYS_BD
                            break;
                        case 6://SATSYS_QZSS
                            break;
                    }
                    //方位角
                    float azimuth = gnssSateInfo.getAzimuth();
                    //高度角
                    float elevation = gnssSateInfo.getElevation();
                    //卫星号
                    int prn = gnssSateInfo.getPrn();
                    //信噪比1
                    float snr1 = gnssSateInfo.getSnr1();
                }
            }

            @Override
            public void OnRtkRespondBack(String strGnssLine) {
                //自己发送的命令返回的@GNSS开头的数据
                Log.d("MainActivity", "OnRtkRespondBack: " + strGnssLine);
            }
        });
    }

    public void showToast(String str) {
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }

    private String getDeviceName(BluetoothDevice device) {
        if (device == null) return "未知设备";

        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                    return device.getAddress();
                }
            }
            String name = device.getName();
            return (name != null && !name.isEmpty()) ? name : device.getAddress();
        } catch (Exception e) {
            e.printStackTrace();
            return device.getAddress();
        }
    }

    //当蓝牙打开时做的操作，打开的话列表中显示以匹配的蓝牙信息
    private void whenOpenBlueTooth() {
        if (bluetoothAdapter == null) {
            return;
        }

        try {
            // 检查蓝牙权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
                        != PackageManager.PERMISSION_GRANTED) {
                    operateBlueTooth.requestPermission();
                    return;
                }
            }

            String address = SpUtils.obtain().getString(LAST_DEVICE);
            //显示已配对的蓝牙item
            bondedDevices = bluetoothAdapter.getBondedDevices();
            if (bondedDevices != null) {
                for (BluetoothDevice bluetoothDevice : bondedDevices) {
                    if (address != null && bluetoothDevice.getAddress().equals(address)) {
                        device = bluetoothDevice;
                    }
                    if (deviceBluetoothAdapter != null) {
                        deviceBluetoothAdapter.addItem(bluetoothDevice);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "获取已配对设备失败", Toast.LENGTH_SHORT).show();
        }
    }

    private void initBlueTooth() {
        try {
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            ryBluetooth.setLayoutManager(new LinearLayoutManager(this));
            deviceBluetoothAdapter = new DeviceBluetoothAdapter(Collections.emptyList());
            ryBluetooth.setAdapter(deviceBluetoothAdapter);
            operateBlueTooth = new BlueToothInit(this, bluetoothAdapter, deviceBluetoothAdapter);
            registerBlueToothReceiver();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initListener() {
        btnSearch.setOnClickListener(this);
        btnStopSearch.setOnClickListener(this);
        btnDisconnect.setOnClickListener(this);
        btnConnect.setOnClickListener(this);
        btnBreakOff.setOnClickListener(this);
    }

    private void initView() {
        tvDeviceName = findViewById(R.id.tv_device_name);
        btnSearch = findViewById(R.id.btn_search);
        btnConnect = findViewById(R.id.btn_connect);
        llConnect = findViewById(R.id.ll_connect);
        llSerach = findViewById(R.id.ll_search);
        llDisconnect = findViewById(R.id.ll_disconnect);
        llBreakOff = findViewById(R.id.ll_break_off);
        btnStopSearch = findViewById(R.id.btn_stop_search);
        btnDisconnect = findViewById(R.id.btn_disconnect);
        btnBreakOff = findViewById(R.id.btn_break_off);
        ryBluetooth = findViewById(R.id.rv_bluetooth);
        flLoading = findViewById(R.id.fl_loading);
        tvLoadingTitle = findViewById(R.id.tv_loading_title);
    }


    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        if (v == btnConnect) {
            onClickConnect();
            return;
        }

        if (v == btnDisconnect) {
            onClickDisconnect();
            return;
        }

        if (v == btnBreakOff) {
            onClickBreakOff();
            return;
        }

        if (v == btnStopSearch) {
            operateBlueTooth.stopSearchBlueTooth();
            return;
        }

        if (v == btnSearch) {
            if(operateBlueTooth.requestPermission()){
                onClickSearchBlueTooth();
            }
        }

    }

    private void onClickBreakOff() {
        updateUIState(BluetoothState.DISCONNECTING);
        GeoManage.getInstance().setAutoConnectBlueTooth(false);
        GeoManage.getInstance().disConnectBlueTooth();
    }

    private void onClickDisconnect() {
        updateUIState(BluetoothState.INITIAL);
        GeoManage.getInstance().disConnectBlueTooth();
    }

    public void onClickSearchBlueTooth() {
        if(!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            showToast("请打开系统位置服务，否则无法搜索蓝牙！");
            return;
        }

        if(deviceBluetoothAdapter != null){
            deviceBluetoothAdapter.setCurrentItem(-1);
            deviceBluetoothAdapter.setmIsClick(false);
            deviceBluetoothAdapter.notifyDataSetChanged();
        }

        if(sets != null && deviceBluetoothAdapter != null){
            deviceBluetoothAdapter.clearData();
            sets.clear();
        }

        updateUIState(BluetoothState.SEARCHING);
        operateBlueTooth.searchBlueTooth();
    }

    private void onClickConnect() {
        if(flLoading.getVisibility() == VISIBLE) return;
        connectToServer();
    }

    //连接服务器
    public void connectToServer(){
        if (!bluetoothAdapter.isEnabled()) {
            showToast("请先打开蓝牙");
            return;
        }
        if(device != null){
            //开始配对
            if(operateBlueTooth.getBondState(device)){//已经成功匹配过，直接开始显示连接对话框
                //开始进行连接
                realStartConnect();
            }

        }else{
            showToast("请选择需要连接的设备!");
        }
    }

    @Override
    public void onDestroy() {
        if(operateBlueTooth != null){
            operateBlueTooth.stopSearchBlueTooth();
        }
        unregisterReceiver(blueToothBroadcastReceiver);
        super.onDestroy();
    }
}